package com.yjq.yys.yhCalculate.utils;

import com.yjq.yys.yhCalculate.entity.Ss;
import com.yjq.yys.yhCalculate.entity.Yh;
import com.yjq.yys.yhCalculate.entity.YhSort;
import com.yjq.yys.yhCalculate.enums.BuffSortEnum;
import com.yjq.yys.yhCalculate.vo.YhCalculateVO;
import com.yjq.yys.yhCalculate.vo.YhExpectVO;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class YhCalculateUtil {

    public static List<YhCalculateVO> calculate(List<Yh> yhList, YhExpectVO expect, Ss ss, List<YhSort> yhSortList) {

        Map<Integer, Set<Integer>> sortIdMap = yhSortList.stream().collect(Collectors.groupingBy(YhSort::getBuffSort, Collectors.mapping(YhSort::getId, Collectors.toSet())));
        Map<Integer, Float> sortRateMap = yhSortList.stream().collect(Collectors.toMap(YhSort::getId, YhSort::getBuffValue));

        Map<Integer, Map<Integer, List<Yh>>> yhMap = getYhMap(yhList, expect);

        Integer primaryIdSort = expect.getPrimarySortId();
        List<Integer> dutySortIdList = expect.getDeputySortId();
        if (CollectionUtils.isEmpty(dutySortIdList)) {
            if(expect.isBanSingle()) {
                dutySortIdList = yhSortList.stream().filter(y -> y.getBuffSort() != 0).map(YhSort::getId).collect(Collectors.toList());
                dutySortIdList.add(0);
            } else {
                dutySortIdList = new ArrayList<>();
                dutySortIdList.add(-1);
            }
        }

        Integer times = 0;
        int minIndex = 0;
        double minTotal = 0;
        Yh[][] yhResultArr = new Yh[expect.getNumber()][6];
        double[] totalArr = new double[expect.getNumber()];
        Arrays.fill(totalArr, 0);
        for (Integer dutySortId : dutySortIdList) {
            for (boolean[] locationSort : LocationSortUtil.locationSortArr) {

                Map<Integer, List<Yh>> yhLocationMap = getYhListMap(yhMap, locationSort, primaryIdSort, dutySortId, sortIdMap);
                for (Yh yh1 : yhLocationMap.get(1)) {
                    for (Yh yh2 : yhLocationMap.get(2)) {
                        for (Yh yh3 : yhLocationMap.get(3)) {
                            for (Yh yh4 : yhLocationMap.get(4)) {
                                for (Yh yh5 : yhLocationMap.get(5)) {
                                    for (Yh yh6 : yhLocationMap.get(6)) {
                                        // 判断速度是否符合
                                        double tempSd = ss.getVelocity() + yh1.getVelocity() + yh2.getVelocity() + yh3.getVelocity() + yh4.getVelocity() + yh5.getVelocity() + yh6.getVelocity();
                                        if(expect.getVelocityMin() != null && tempSd < expect.getVelocityMin()) {
                                            continue;
                                        } else if(expect.getVelocityMax() != null && tempSd > expect.getVelocityMax()) {
                                            continue;
                                        }
                                        // 判断 暴击是否相符
                                        int[] sortArr = new int[]{yh1.getYhSortId(), yh2.getYhSortId(), yh3.getYhSortId(), yh4.getYhSortId(), yh5.getYhSortId(), yh6.getYhSortId()};
                                        double tempBj = ss.getCritRate() + getRate(sortIdMap.get(BuffSortEnum.CRIT_RATE.getIndex()), sortRateMap, sortArr) + yh1.getCritRate() + yh2.getCritRate() + yh3.getCritRate() + yh4.getCritRate() + yh5.getCritRate() + yh6.getCritRate();
                                        if(expect.getCritRateMin() != null && tempBj < expect.getCritRateMin()) {
                                            continue;
                                        }

                                        //log.info("---正在进行第" + times++ + "次计算---");
                                        double tempTotal = calculateResult(expect, ss, yh1, yh2, yh3, yh4, yh5, yh6, sortIdMap, sortRateMap);
                                        //log.info("计算数值为: " + tempTotal);
                                        if(expect.getTotalMax() != null && tempTotal > expect.getTotalMax()) {
                                            continue;
                                        }
                                        if (tempTotal > minTotal) {
                                            totalArr[minIndex] = tempTotal;
                                            yhResultArr[minIndex][0] = yh1;
                                            yhResultArr[minIndex][1] = yh2;
                                            yhResultArr[minIndex][2] = yh3;
                                            yhResultArr[minIndex][3] = yh4;
                                            yhResultArr[minIndex][4] = yh5;
                                            yhResultArr[minIndex][5] = yh6;
                                            minIndex = getMinTotalIndex(totalArr);
                                            minTotal = totalArr[minIndex];
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        log.info("-----------------------");
        log.info("计算完成，总计算" + times + "次");
        log.info("结果如下");
        log.info("~~~~~~~~~~~~~~~~~~~~~~~");

        List<YhCalculateVO> vo = getListVO(ss, totalArr, yhResultArr, sortIdMap, sortRateMap);
        log.info(JSONArray.fromObject(vo).toString());
        return vo;

    }

    private static Map<Integer, List<Yh>> getYhListMap (Map<Integer, Map<Integer, List<Yh>>> yhMap, boolean[] locationSortArr, Integer primarySortId, Integer dutySortId, Map<Integer, Set<Integer>> sortIdMap) {

        Map<Integer, List<Yh>> resultMap = new HashMap<>();

        for(int i = 1; i <= 6; i++ ) {
            Map<Integer, List<Yh>> sortMap = yhMap.get(i) != null ? yhMap.get(i) : new HashMap<>();
            Integer sortId = locationSortArr[i - 1] ? primarySortId : dutySortId;
            if(sortId == 0) {
                List<Yh> tempList = new ArrayList<>();
                Set<Integer> zeroBuffIdSet = sortIdMap.get(0);
                if(zeroBuffIdSet != null && zeroBuffIdSet.size() > 0) {
                    for(Integer zeroSortId : zeroBuffIdSet) {
                        if(sortMap.get(zeroSortId) != null) {
                            tempList.addAll(sortMap.get(zeroSortId));
                        }
                    }
                }
                resultMap.put(i, tempList);
            } else if(sortId == -1) {
                resultMap.put(i, sortMap.values().stream().flatMap(List::stream).collect(Collectors.toList()));
            } else {
                resultMap.put(i, sortMap.get(sortId) != null ? sortMap.get(sortId) : new ArrayList<>());
            }
        }

        return resultMap;
    }

    private static Map<Integer, Map<Integer, List<Yh>>> getYhMap(List<Yh> yhList, YhExpectVO expect) {

        Map<Integer, List<Yh>> yhLocationMap = yhList.stream()
                .filter(y -> y.getLocation() != 2 || expect.getSort2() == null || expect.getSort2().contains(y.getMainBuff()))
                .filter(y -> y.getLocation() != 4 || expect.getSort4() == null || expect.getSort4().contains(y.getMainBuff()))
                .filter(y -> y.getLocation() != 6 || expect.getSort6() == null || expect.getSort6().contains(y.getMainBuff()))
                .collect(Collectors.groupingBy(Yh::getLocation));

        Map<Integer, Map<Integer, List<Yh>>> yhMap = new HashMap<>();
        for(Map.Entry<Integer, List<Yh>> entity : yhLocationMap.entrySet()) {
            yhMap.put(entity.getKey(), entity.getValue().stream().collect(Collectors.groupingBy(Yh::getYhSortId)));
        }

        return yhMap;
    }

    private static List<YhCalculateVO> getListVO(Ss ss, double[] totalArr, Yh[][] yhArr, Map<Integer, Set<Integer>> sortIdMap, Map<Integer, Float> sortRateMap) {

        List<YhCalculateVO> resultList = new ArrayList<>();
        for (int i = 0; i < totalArr.length; i++) {
            if(totalArr[i] <= 0) {
                continue;
            }
            YhCalculateVO calculateVO = new YhCalculateVO();
            calculateVO.setSs(ss);
            calculateVO.setTotalValue(totalArr[i]);
            calculateVO.setYhList(Arrays.asList(yhArr[i]));
            calculateVO.setYhAttribute(getYhAttribute(ss, yhArr[i], sortIdMap, sortRateMap));
            resultList.add(calculateVO);
        }
        resultList.sort(Comparator.comparing(YhCalculateVO::getTotalValue).reversed());
        return resultList;
    }

    private static Yh getYhAttribute(Ss ss, Yh[] yhArr, Map<Integer, Set<Integer>> sortIdMap, Map<Integer, Float> sortRateMap) {

        Yh result = new Yh();
        int[] sortArr = new int[]{yhArr[0].getYhSortId(), yhArr[1].getYhSortId(), yhArr[2].getYhSortId(), yhArr[3].getYhSortId(), yhArr[4].getYhSortId(), yhArr[5].getYhSortId()};

        double attackValue = yhArr[0].getAttackValue() + yhArr[1].getAttackValue() + yhArr[2].getAttackValue() + yhArr[3].getAttackValue() + yhArr[4].getAttackValue() + yhArr[5].getAttackValue();
        double attackRate = getRate(sortIdMap.get(BuffSortEnum.ATTACK_RATE.getIndex()), sortRateMap, sortArr) + yhArr[0].getAttackRate() + yhArr[1].getAttackRate() + yhArr[2].getAttackRate() + yhArr[3].getAttackRate() + yhArr[4].getAttackRate() + yhArr[5].getAttackRate();
        result.setAttackValue(ss.getAttack() * attackRate + attackValue);

        double critRate = getRate(sortIdMap.get(BuffSortEnum.CRIT_RATE.getIndex()), sortRateMap, sortArr) + yhArr[0].getCritRate() + yhArr[1].getCritRate() + yhArr[2].getCritRate() + yhArr[3].getCritRate() + yhArr[4].getCritRate() + yhArr[5].getCritRate();
        double critDamage = yhArr[0].getCritDamage() + yhArr[1].getCritDamage() + yhArr[2].getCritDamage() + yhArr[3].getCritDamage() + yhArr[4].getCritDamage() + yhArr[5].getCritDamage();
        result.setCritRate(critRate);
        result.setCritDamage(critDamage);

        double defenceValue = yhArr[0].getDefenceValue() + yhArr[1].getDefenceValue() + yhArr[2].getDefenceValue() + yhArr[3].getDefenceValue() + yhArr[4].getDefenceValue() + yhArr[5].getDefenceValue();
        double defenceRate = getRate(sortIdMap.get(BuffSortEnum.DEFENCE_RATE.getIndex()), sortRateMap, sortArr) + yhArr[0].getDefenceRate() + yhArr[1].getDefenceRate() + yhArr[2].getDefenceRate() + yhArr[3].getDefenceRate() + yhArr[4].getDefenceRate() + yhArr[5].getDefenceRate();
        result.setDefenceValue(ss.getHealthPoint() * defenceRate + defenceValue);

        double healthPointValue = yhArr[0].getHealthPointValue() + yhArr[1].getHealthPointValue() + yhArr[2].getHealthPointValue() + yhArr[3].getHealthPointValue() + yhArr[4].getHealthPointValue() + yhArr[5].getHealthPointValue();
        double healthPointRate = getRate(sortIdMap.get(BuffSortEnum.HEALTH_POINT_RATE.getIndex()), sortRateMap, sortArr) + yhArr[0].getHealthPointRate() + yhArr[1].getHealthPointRate() + yhArr[2].getHealthPointRate() + yhArr[3].getHealthPointRate() + yhArr[4].getHealthPointRate() + yhArr[5].getHealthPointRate();
        result.setHealthPointValue(ss.getHealthPoint() * healthPointRate + healthPointValue);

        result.setVelocity(yhArr[0].getVelocity() + yhArr[1].getVelocity() + yhArr[2].getVelocity() + yhArr[3].getVelocity() + yhArr[4].getVelocity() + yhArr[5].getVelocity());
        result.setEffectHit(getRate(sortIdMap.get(BuffSortEnum.EFFECT_HIT.getIndex()), sortRateMap, sortArr) + yhArr[0].getEffectHit() + yhArr[1].getEffectHit() + yhArr[2].getEffectHit() + yhArr[3].getEffectHit() + yhArr[4].getEffectHit() + yhArr[5].getEffectHit());
        result.setEffectAvoid(getRate(sortIdMap.get(BuffSortEnum.EFFECT_AVOID.getIndex()), sortRateMap, sortArr) + yhArr[0].getEffectAvoid() + yhArr[1].getEffectAvoid() + yhArr[2].getEffectAvoid() + yhArr[3].getEffectAvoid() + yhArr[4].getEffectAvoid() + yhArr[5].getEffectAvoid());

        return result;
    }

    private static double calculateResult(YhExpectVO expect, Ss ss, Yh yh1, Yh yh2, Yh yh3, Yh yh4, Yh yh5, Yh yh6, Map<Integer, Set<Integer>> sortIdMap, Map<Integer, Float> sortRateMap) {

        int[] sortArr = new int[]{yh1.getYhSortId(), yh2.getYhSortId(), yh3.getYhSortId(), yh4.getYhSortId(), yh5.getYhSortId(), yh6.getYhSortId()};

        double result, attackValue, healthPointValue, defenceValue, attackRate, healthPointRate, defenceRate, critRate, critDamage;

        if (expect.getType() == 1) {
            switch (expect.getAttribute()) {
                // 攻击
                case 1:
                    attackValue = yh1.getAttackValue() + yh2.getAttackValue() + yh3.getAttackValue() + yh4.getAttackValue() + yh5.getAttackValue() + yh6.getAttackValue();
                    attackRate = getRate(sortIdMap.get(BuffSortEnum.ATTACK_RATE.getIndex()), sortRateMap, sortArr) + yh1.getAttackRate() + yh2.getAttackRate() + yh3.getAttackRate() + yh4.getAttackRate() + yh5.getAttackRate() + yh6.getAttackRate();
                    result = ss.getAttack() * (1 + attackRate) + attackValue;
                    return expect.isHkl() && haveHkl(sortArr) ? result * 1.1F : result;
                // 攻击X爆伤
                case 8:
                    attackValue = yh1.getAttackValue() + yh2.getAttackValue() + yh3.getAttackValue() + yh4.getAttackValue() + yh5.getAttackValue() + yh6.getAttackValue();
                    attackRate = getRate(sortIdMap.get(BuffSortEnum.ATTACK_RATE.getIndex()), sortRateMap, sortArr) + yh1.getAttackRate() + yh2.getAttackRate() + yh3.getAttackRate() + yh4.getAttackRate() + yh5.getAttackRate() + yh6.getAttackRate();
                    critDamage = ss.getCritDamage() + yh1.getCritDamage() + yh2.getCritDamage() + yh3.getCritDamage() + yh4.getCritDamage() + yh5.getCritDamage() + yh6.getCritDamage();
                    result = (ss.getAttack() * (1 + attackRate) + attackValue) * critDamage;
                    return expect.isHkl() && haveHkl(sortArr) ? result * 1.1F : result;
                // 攻击X暴X爆
                case 2:
                    attackValue = yh1.getAttackValue() + yh2.getAttackValue() + yh3.getAttackValue() + yh4.getAttackValue() + yh5.getAttackValue() + yh6.getAttackValue();
                    attackRate = getRate(sortIdMap.get(BuffSortEnum.ATTACK_RATE.getIndex()), sortRateMap, sortArr) + yh1.getAttackRate() + yh2.getAttackRate() + yh3.getAttackRate() + yh4.getAttackRate() + yh5.getAttackRate() + yh6.getAttackRate();
                    critRate = getRate(sortIdMap.get(BuffSortEnum.CRIT_RATE.getIndex()), sortRateMap, sortArr) + ss.getCritRate() + yh1.getCritRate() + yh2.getCritRate() + yh3.getCritRate() + yh4.getCritRate() + yh5.getCritRate() + yh6.getCritRate();
                    critDamage = ss.getCritDamage() + yh1.getCritDamage() + yh2.getCritDamage() + yh3.getCritDamage() + yh4.getCritDamage() + yh5.getCritDamage() + yh6.getCritDamage();
                    if (critRate > 1) {
                        critRate = 1;
                    }
                    result = (ss.getAttack() * (1 + attackRate) + attackValue) * ((1 - critRate) + critRate * critDamage);
                    return expect.isHkl() && haveHkl(sortArr) ? result * 1.1F : result;
                // 生命
                case 3:
                    healthPointValue = yh1.getHealthPointValue() + yh2.getHealthPointValue() + yh3.getHealthPointValue() + yh4.getHealthPointValue() + yh5.getHealthPointValue() + yh6.getHealthPointValue();
                    healthPointRate = getRate(sortIdMap.get(BuffSortEnum.HEALTH_POINT_RATE.getIndex()), sortRateMap, sortArr) + yh1.getHealthPointRate() + yh2.getHealthPointRate() + yh3.getHealthPointRate() + yh4.getHealthPointRate() + yh5.getHealthPointRate() + yh6.getHealthPointRate();
                    result = ss.getHealthPoint() * (1 + healthPointRate) + healthPointValue;
                    return expect.isHkl() && haveHkl(sortArr) ? result * 1.1F : result;
                // 生命X爆伤
                case 4:
                    healthPointValue = yh1.getHealthPointValue() + yh2.getHealthPointValue() + yh3.getHealthPointValue() + yh4.getHealthPointValue() + yh5.getHealthPointValue() + yh6.getHealthPointValue();
                    healthPointRate = getRate(sortIdMap.get(BuffSortEnum.HEALTH_POINT_RATE.getIndex()), sortRateMap, sortArr) + yh1.getHealthPointRate() + yh2.getHealthPointRate() + yh3.getHealthPointRate() + yh4.getHealthPointRate() + yh5.getHealthPointRate() + yh6.getHealthPointRate();
                    critDamage = ss.getCritDamage() + yh1.getCritDamage() + yh2.getCritDamage() + yh3.getCritDamage() + yh4.getCritDamage() + yh5.getCritDamage() + yh6.getCritDamage();
                    result = (ss.getHealthPoint() * (1 + healthPointRate) + healthPointValue) * critDamage;
                    return expect.isHkl() && haveHkl(sortArr) ? result * 1.1F : result;
                // 生命X暴X爆
                case 9:
                    healthPointValue = yh1.getHealthPointValue() + yh2.getHealthPointValue() + yh3.getHealthPointValue() + yh4.getHealthPointValue() + yh5.getHealthPointValue() + yh6.getHealthPointValue();
                    healthPointRate = getRate(sortIdMap.get(BuffSortEnum.HEALTH_POINT_RATE.getIndex()), sortRateMap, sortArr) + yh1.getHealthPointRate() + yh2.getHealthPointRate() + yh3.getHealthPointRate() + yh4.getHealthPointRate() + yh5.getHealthPointRate() + yh6.getHealthPointRate();
                    critRate = getRate(sortIdMap.get(BuffSortEnum.CRIT_RATE.getIndex()), sortRateMap, sortArr) + ss.getCritRate() + yh1.getCritRate() + yh2.getCritRate() + yh3.getCritRate() + yh4.getCritRate() + yh5.getCritRate() + yh6.getCritRate();
                    critDamage = ss.getCritDamage() + yh1.getCritDamage() + yh2.getCritDamage() + yh3.getCritDamage() + yh4.getCritDamage() + yh5.getCritDamage() + yh6.getCritDamage();
                    if (critRate > 1) {
                        critRate = 1;
                    }
                    result = (ss.getHealthPoint() * (1 + healthPointRate) + healthPointValue) * ((1 - critRate) + critRate * critDamage);
                    return expect.isHkl() && haveHkl(sortArr) ? result * 1.1F : result;

                case 5:
                    return ss.getVelocity() + yh1.getVelocity() + yh2.getVelocity() + yh3.getVelocity() + yh4.getVelocity() + yh5.getVelocity() + yh6.getVelocity();

                case 6:
                    return ss.getEffectHit() + getRate(sortIdMap.get(BuffSortEnum.EFFECT_HIT.getIndex()), sortRateMap, sortArr) + yh1.getEffectHit() + yh2.getEffectHit() + yh3.getEffectHit() + yh4.getEffectHit() + yh5.getEffectHit() + yh6.getEffectHit();

                case 7:
                    return ss.getEffectAvoid() + getRate(sortIdMap.get(BuffSortEnum.EFFECT_AVOID.getIndex()), sortRateMap, sortArr) + yh1.getEffectAvoid() + yh2.getEffectAvoid() + yh3.getEffectAvoid() + yh4.getEffectAvoid() + yh5.getEffectAvoid() + yh6.getEffectAvoid();

                // 自定义
                case 10:
                    String expression = expect.getExpression();
                    if(expression.contains("bjsh")) {
                        expression = expression.replace("bjsh", "((1 - bj) + bj * bs)");
                    }
                    if(expression.contains("gj")) {
                        attackValue = yh1.getAttackValue() + yh2.getAttackValue() + yh3.getAttackValue() + yh4.getAttackValue() + yh5.getAttackValue() + yh6.getAttackValue();
                        attackRate = getRate(sortIdMap.get(BuffSortEnum.ATTACK_RATE.getIndex()), sortRateMap, sortArr) + yh1.getAttackRate() + yh2.getAttackRate() + yh3.getAttackRate() + yh4.getAttackRate() + yh5.getAttackRate() + yh6.getAttackRate();
                        expression = expression.replace("gj", String.valueOf(ss.getAttack() * (1 + attackRate) + attackValue));
                    }
                    if(expression.contains("sm")) {
                        healthPointValue = yh1.getHealthPointValue() + yh2.getHealthPointValue() + yh3.getHealthPointValue() + yh4.getHealthPointValue() + yh5.getHealthPointValue() + yh6.getHealthPointValue();
                        healthPointRate = getRate(sortIdMap.get(BuffSortEnum.HEALTH_POINT_RATE.getIndex()), sortRateMap, sortArr) + yh1.getHealthPointRate() + yh2.getHealthPointRate() + yh3.getHealthPointRate() + yh4.getHealthPointRate() + yh5.getHealthPointRate() + yh6.getHealthPointRate();
                        expression = expression.replace("sm", String.valueOf(ss.getHealthPoint() * (1 + healthPointRate) + healthPointValue));
                    }
                    if(expression.contains("fy")) {
                        defenceValue = yh1.getDefenceValue() + yh2.getDefenceValue() + yh3.getDefenceValue() + yh4.getDefenceValue() + yh5.getDefenceValue() + yh6.getDefenceValue();
                        defenceRate = getRate(sortIdMap.get(BuffSortEnum.DEFENCE_RATE.getIndex()), sortRateMap, sortArr) + yh1.getDefenceRate() + yh2.getDefenceRate() + yh3.getDefenceRate() + yh4.getDefenceRate() + yh5.getDefenceRate() + yh6.getDefenceRate();
                        expression = expression.replace("fy", String.valueOf(ss.getHealthPoint() * (1 + defenceRate) + defenceValue));
                    }
                    if(expression.contains("sd")) {
                        expression = expression.replace("sd", String.valueOf(ss.getVelocity() + yh1.getVelocity() + yh2.getVelocity() + yh3.getVelocity() + yh4.getVelocity() + yh5.getVelocity() + yh6.getVelocity()));
                    }
                    if(expression.contains("xgmz")) {
                        expression = expression.replace("xgmz", String.valueOf(ss.getEffectHit() + getRate(sortIdMap.get(BuffSortEnum.EFFECT_HIT.getIndex()), sortRateMap, sortArr) + yh1.getEffectHit() + yh2.getEffectHit() + yh3.getEffectHit() + yh4.getEffectHit() + yh5.getEffectHit() + yh6.getEffectHit()));
                    }
                    if(expression.contains("xgdk")) {
                        expression = expression.replace("xgdk", String.valueOf(ss.getEffectAvoid() + getRate(sortIdMap.get(BuffSortEnum.EFFECT_AVOID.getIndex()), sortRateMap, sortArr) + yh1.getEffectAvoid() + yh2.getEffectAvoid() + yh3.getEffectAvoid() + yh4.getEffectAvoid() + yh5.getEffectAvoid() + yh6.getEffectAvoid()));
                    }
                    if(expression.contains("bj")) {
                        double bj = ss.getCritRate() + getRate(sortIdMap.get(BuffSortEnum.CRIT_RATE.getIndex()), sortRateMap, sortArr) +  + yh1.getCritRate() + yh2.getCritRate() + yh3.getCritRate() + yh4.getCritRate() + yh5.getCritRate() + yh6.getCritRate();
                        bj = bj > 1 ? 1 : bj;
                        expression = expression.replace("bj", String.valueOf(bj));
                    }
                    if(expression.contains("bs")) {
                        expression = expression.replace("bs", String.valueOf(ss.getCritDamage() + yh1.getCritDamage() + yh2.getCritDamage() + yh3.getCritDamage() + yh4.getCritDamage() + yh5.getCritDamage() + yh6.getCritDamage()));
                    }
                    return ExpressionUtil.result(expression);
                default:
                    return 0;
            }

        } else {
            return 0;
        }

    }

    private static int getMinTotalIndex(double[] totalArr) {
        int result = 0;
        double minTotal = totalArr[0];

        for (int i = 1; i < totalArr.length; i++) {
            if (totalArr[i] < minTotal) {
                result = i;
                minTotal = totalArr[i];
            }
        }
        return result;
    }

    private static float getRate(Set<Integer> idSet, Map<Integer, Float> sortRateMap, int[] sortArr) {

        float result = 0;

        Map<Integer, Boolean> flagMap = new HashMap<>(6);
        for (int sortId : sortArr) {
            if (!idSet.contains(sortId)) {
                continue;
            }
            Boolean flag = flagMap.get(sortId);
            if (flag == null) {
                flagMap.put(sortId, false);
            } else if (!flag) {
                result += sortRateMap.get(sortId);
                flagMap.put(sortId, true);
            }
        }
        return result;
    }

    private static boolean haveHkl(int[] sortIdArr) {

        int total = 0;
        for (int sortId : sortIdArr) {
            if (sortId == 36) {
                total++;
            }
        }
        return total > 1;
    }

}
